import xmlrpc.client as  xmlrpclib
import logging

from django.conf import settings

from supervisor_dj.models import Supervisor_Process, SupervisorHost, Supervisor_Action_History
from .tasks import supervisor_processlist_status_update_task, write_msg_to_log_and_db_task

logger = logging.getLogger()

SUPERVISOR_PASS = getattr(settings, 'SUPERVISOR_PASS', None)
SUPERVISOR_USER = getattr(settings, 'SUPERVISOR_USER', None)


class Supervisor_Process_Managet_Class:
    msg_res = {"status_code": True, "msg": None}

    def __init__(self, username=None, password=None, ip=None, port=None):
        self.username = username if username else SUPERVISOR_USER
        self.password = password if password else SUPERVISOR_PASS
        self.ip = ip
        self.port = port if port else 9001

    def get_connection(self, ip=None, port=None):
        # 获取连接对象
        if not port:
            port = self.port
        return get_connection_func(ip=ip, port=port, username=self.username, password=self.password)

    def action(self, process_name=None, ip=None, action_method=None):

        """
        启动,停止,重启
        """
        res_data = {}

        supervisor_obj = Supervisor_Process.objects.filter(name=process_name, ip=ip)
        if not supervisor_obj.exists():
            msg = message_res(
                action_name=action_method,
                ip=ip,
                process_name=process_name,
                status_code=False,
                msg="所操作对象不存在"
            )
            res_data["msg"] = msg

            return res_data

        # 进程对象
        supervisor_obj = supervisor_obj.first()

        # 所属主机
        supervisor_host = supervisor_obj.supervisor_host

        # 获取连接对象
        super_obj = self.get_connection(ip=supervisor_obj.ip, port=supervisor_host.port)

        try:
            # 实时获取进程状态
            supervisor_obj_current_status = super_obj.getProcessInfo(process_name)["statename"]

            if action_method == 'start':
                # 启动进程
                super_obj.startProcess(process_name)
            elif action_method == 'stop':
                # 停止进程
                super_obj.stopProcess(process_name)

            elif action_method == 'restart':
                # 重启进程  检查当前进程运行状态,正在运行则先停止在启动, 否则直接启动
                if supervisor_obj_current_status == "STOPPED":
                    super_obj.startProcess(process_name)

                if supervisor_obj_current_status == "RUNNING":
                    msg = f"准备重启1,当前状态为{supervisor_obj_current_status}"
                    logger.info(msg)
                    super_obj.stopProcess(process_name)
                    msg = f"准备重启1,当前状态为STOPPED"
                    logger.warning(msg)
                    super_obj.startProcess(process_name)

            # 记录操作历史

            msg = message_res(
                action_name=action_method,
                ip=ip,
                process_name=process_name,
                status_code=True,
                msg="操作成功"
            )
            res_data["msg"] = msg

            # 实时进程信息
            process_status_data = self.get_process_info_list(ip=ip)
            res_data["process_status_data"] = process_status_data

            return res_data

        except xmlrpclib.Fault  as e:
            msg = e.faultString
            msg_res = message_res(
                action_name=action_method,
                ip=ip,
                process_name=process_name,
                status_code=False,
                msg=msg
            )

            res_data["msg"] = msg_res
            return res_data

        except Exception as e:
            msg = e
            msg_res = message_res(
                action_name=action_method,
                ip=ip,
                process_name=process_name,
                status_code=False,
                msg=msg
            )

            res_data["msg"] = msg_res
            return res_data


    def get_process_info_list(self, ip=None):
        """ 获取进程信息列表信息 """

        super_conn_obj = self.get_connection(ip=ip)
        res_msg = {"status_code": False}
        try:
            # 获取进程信息
            process_info_list = super_conn_obj.getAllProcessInfo()
            res_msg["status_code"] = True
            res_msg["data"] = process_info_list
            return res_msg
        except xmlrpclib.Fault as e:
            res_msg["data"] = e.faultString
            return res_msg
        except Exception as e:
            res_msg["data"] = e
            return res_msg


def get_connection_func(ip=None, port=None, username=None, password=None):
    """
    返回连接对象
    :return:  server = xmlrpclib.Server('http://zrd:sh123!@192.168.1.60:9001/RPC2/')
    """
    if username and password:
        # 有密码和账号
        connection_info = f'http://{username}:{password}@{ip}:{port}/RPC2/'
        server = xmlrpclib.Server(connection_info).supervisor
        return server

    # 无密码和账号
    connection_info_no_pass = f'http://{ip}:{port}/RPC2/'
    server = xmlrpclib.Server(connection_info_no_pass).supervisor
    return server


def message_res(action_name=None, ip=None, process_name=None, status_code=None, user=None, msg=None):
    msg_res = {
        "action_name": action_name,
        "ip": ip,
        "process_name": process_name,
        "status_code": status_code,
        "user": user,
        "msg": msg
    }
    return msg_res
